/**********************************************************************
* Filename: Pais.java
* Created: 2012/04/30
* @author Fernando Brito e Abreu
**********************************************************************/
package org.bunny.businessLayer;

import java.util.Set;
import java.util.HashSet;

public class Pais{
	public static Set<Pais> allInstances = new HashSet<Pais>();
	
	private int area;
	private String nome;
	private int populacao;
	private Continente continente;
	private Grupo grupo;
	
	/**********************************************************************
	* Default constructor
	**********************************************************************/
	public Pais(){
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Parameterized constructor
	* @param area the area to initialize
	* @param nome the nome to initialize
	* @param populacao the populacao to initialize
	* @param continente the continente to initialize
	* @param grupo the grupo to initialize
	**********************************************************************/
	public Pais(int area, String nome, int populacao, Continente continente, Grupo grupo){
		this.area = area;
		this.nome = nome;
		this.populacao = populacao;
		this.continente = continente;
		this.grupo = grupo;
		allInstances.add(this);
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the area of the pais
	**********************************************************************/
	public int area(){
		return area;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param area the area to set
	**********************************************************************/
	public void setArea(int area){
		this.area = area;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the nome of the pais
	**********************************************************************/
	public String nome(){
		return nome;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param nome the nome to set
	**********************************************************************/
	public void setNome(String nome){
		this.nome = nome;
	}
	
	/**********************************************************************
	* Standard attribute getter
	* @return the populacao of the pais
	**********************************************************************/
	public int populacao(){
		return populacao;
	}
	
	/**********************************************************************
	* Standard attribute setter
	* @param populacao the populacao to set
	**********************************************************************/
	public void setPopulacao(int populacao){
		this.populacao = populacao;
	}
	
	/**********************************************************************
	* ONE2MANY getter for Pais[*] <-> Continente[1]
	* @return the continente of the pais
	**********************************************************************/
	public Continente continente(){
		return continente;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Pais[*] <-> Continente[1]
	* @param continente the continente to set
	**********************************************************************/
	public void setContinente(Continente continente){
		this.continente = continente;
	}
	
	/**********************************************************************
	* ONE2MANY getter for Pais[*] <-> Grupo[1]
	* @return the grupo of the pais
	**********************************************************************/
	public Grupo grupo(){
		return grupo;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Pais[*] <-> Grupo[1]
	* @param grupo the grupo to set
	**********************************************************************/
	public void setGrupo(Grupo grupo){
		this.grupo = grupo;
	}
	
	/**********************************************************************
	* ONE2MANY getter for Pais[1] <-> Clube[*]
	* @return the clubes of the pais
	**********************************************************************/
	public Set<Clube> clubes(){
		Set<Clube> result = new HashSet<Clube>();
		for (Clube x : Clube.allInstances){
			if (x.pais()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Pais[1] <-> Clube[*]
	* @param clubes the clubes to set
	**********************************************************************/
	public void setClubes(Set<Clube> clubes){
		for (Clube x : clubes){
			x.setPais(this);
		}
	}
	
	/**********************************************************************
	* ONE2MANY getter for Pais[1] <-> Participante[*]
	* @return the nacionais of the nacionalidade
	**********************************************************************/
	public Set<Participante> nacionais(){
		Set<Participante> result = new HashSet<Participante>();
		for (Participante x : Participante.allInstances()){
			if (x.nacionalidade()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Pais[1] <-> Participante[*]
	* @param nacionais the nacionais to set
	**********************************************************************/
	public void setNacionais(Set<Participante> nacionais){
		for (Participante x : nacionais){
			x.setNacionalidade(this);
		}
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE getter for Pais[2] <-> Equipa[*]
	* @return the equipa of the seleccao
	**********************************************************************/
	public Set<Equipa> equipa(){
		Set<Equipa> result = new HashSet<Equipa>();
		for (Equipa x : Equipa.allInstances){
			if (x.seleccao()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE setter for Pais[2] <-> Equipa[*]
	* @param equipa the equipa to set
	**********************************************************************/
	public void setEquipa(Set<Equipa> equipa){
		for (Equipa x : equipa){
			x.setSeleccao(this);
		}
	}
	
	/**********************************************************************
	* MEMBER2MEMBER getter for Pais[2] <-> Jogo[*]
	* @return the jogo of the seleccao
	**********************************************************************/
	public Set<Jogo> jogo(){
		Set<Jogo> result = new HashSet<Jogo>();
		for (Equipa x : Equipa.allInstances){
			if (x.seleccao()  ==  this)
				result.add(x.jogo());
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2MEMBER setter for Pais[2] <-> Jogo[*]
	* @param jogo the jogo to set
	**********************************************************************/
	public void setJogo(Set<Jogo> jogo){
		for (Jogo t : jogo){
			for (Equipa x: Equipa.allInstances){
				if (x.seleccao() == this)
					x.setJogo(t);
			}
		}
	}
	
	/**********************************************************************
	* ONE2MANY getter for Pais[1] <-> Cidade[*]
	* @return the cidades of the pais
	**********************************************************************/
	public Set<Cidade> cidades(){
		Set<Cidade> result = new HashSet<Cidade>();
		for (Cidade x : Cidade.allInstances){
			if (x.pais()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* ONE2MANY setter for Pais[1] <-> Cidade[*]
	* @param cidades the cidades to set
	**********************************************************************/
	public void setCidades(Set<Cidade> cidades){
		for (Cidade x : cidades){
			x.setPais(this);
		}
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE getter for Pais[2..*] <-> Participacao[*]
	* @return the participacao of the participante
	**********************************************************************/
	public Set<Participacao> participacao(){
		Set<Participacao> result = new HashSet<Participacao>();
		for (Participacao x : Participacao.allInstances){
			if (x.participante()  ==  this)
				result.add(x);
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2ASSOCIATIVE setter for Pais[2..*] <-> Participacao[*]
	* @param participacao the participacao to set
	**********************************************************************/
	public void setParticipacao(Set<Participacao> participacao){
		for (Participacao x : participacao){
			x.setParticipante(this);
		}
	}
	
	/**********************************************************************
	* MEMBER2MEMBER getter for Pais[2..*] <-> Campeonato[*]
	* @return the participado of the participante
	**********************************************************************/
	public Set<Campeonato> participado(){
		Set<Campeonato> result = new HashSet<Campeonato>();
		for (Participacao x : Participacao.allInstances){
			if (x.participante()  ==  this)
				result.add(x.participado());
		}
		return result;
	}
	
	/**********************************************************************
	* MEMBER2MEMBER setter for Pais[2..*] <-> Campeonato[*]
	* @param participado the participado to set
	**********************************************************************/
	public void setParticipado(Set<Campeonato> participado){
		for (Campeonato t : participado){
			for (Participacao x: Participacao.allInstances){
				if (x.participante() == this)
					x.setParticipado(t);
			}
		}
	}
	
//	/**********************************************************************
//	* User-defined operation specified in SOIL/OCL
//	* @param nome the nome to set
//	* @param populacao the populacao to set
//	* @param area the area to set
//	* @param continente the continente to set
//	**********************************************************************/
//	public void inicializa(String nome, int populacao, int area, Continente continente)
//	{
//		//	TODO
//		//	self.nome := nome;
//		//	 self.populacao := populacao;
//		//	 self.area := area;
//		//	 insert (continente,self) into Continente_Pais;
//	}
	
	//	PRE-CONDITIONS (TODO)
	/*
	pre ArgumentosPaisForamInicializados
		(((nome.isDefined and area.isDefined) and continente.isDefined) and Continente.allInstances->includes(continente))
	
	*/
	
	//	POST-CONDITIONS (TODO)
	/*
	post PaisInicializado
		((self.nome.isDefined and self.populacao.isDefined) and self.area.isDefined)
	
	*/
	
	/* (non-Javadoc)
	* @see java.lang.Object#toString()
	*/
	@Override
	/**********************************************************************
	* Object serializer
	**********************************************************************/
	public String toString(){
		return "Pais [area=" + area + ", nome=" + nome + ", populacao=" + populacao + ", continente=" + continente + ", grupo=" + grupo + "]\n";
	}
	
	//	-------------------------------------------------------------------------------
	//	INVARIANTS (TODO)
	/*
	inv TamanhoMaxNome
		((self.nome.size > 2) and (self.nome.size < 64))
	
	inv AreaMinMaxPais
		((self.area > 0.4) and (self.area < 18000000))
	
	inv PopulacaoMinMaxPais
		((self.populacao > 50) and (self.populacao < 1400000000))
	
	*/
}
